第80回InfoTalkで「ChatWork、再実装の決断と裏側」を聞いてきた
ウィスキー、シガー、パイプをこよなく愛する大栗です。 先日、産業技術大学院大学で開催されているInfoTalkに参加して、チャットワークのCTOである山本さんの話を伺ったのでレポートします。
ChatWork、再実装の決断と裏側
チャットワークについて
CharWork社について
日本は東京、大阪にオフィスがあり、アメリカのロサンゼルスにもオフィスがあります。 アメリカへCEOの山本さん(CTO山本さんのお兄さんです)が移住されています。
チャットワークとは
チャットワークとはクラウド型ビジネスチャットツール。 導入企業は7万7千社を突破している!
チャットワークの規模
2015年8月の規模は以下のとおりです。
メッセージ数 | 約7億9千万 |
チャットルーム数 | 約2千300万 |
タスク数 | 約3千900万 |
ファイル数 | 約3千100万(約76TB) |
チャットワークの開発体制
CTOの元にWeb開発、基板開発部、アプリケーション開発部、CTO室という体制になっています。
チャットワークの歴史
2011年にリリースしてから3年・・・ 全システムを再実装することを決断しました。
もちろん簡単ではありません。
チャットワークのはじまり
開発をはじめる前の状況(2010年)
- ひとつ前につくっていたWebサービスが大失敗、、、
- 会社としてWebサービス自体に挫折感がただよう
- 会社としてはWebとリアルの融合という方向に注力
チャットワークを思いつく
- 敗戦処理に追われる日々・・・
- 何かやりたいなぁとチャットワークの企画を思いつく
- これはイケる!と大興奮して提案したところ・・・
見事に企画を却下されました・・・
却下された理由
ひとつ前につくったWebサービスが大ゴケしたばっかだよね・・・ Google Waveが出たばっかりで勢いがあった
でも諦められずに・・・
絶対イケるから!と役員をひとりずつ呼び出して説得 社長からなんとか「そこまで言うなら、最悪社内ツールにすればいいか」という言葉を引き出すことに成功!
社長からの一言
というわけで
- 一人プロジェクトとして開発スタート
- まずは社内ツールでの定着を目指すことに(期待されていない)
- 社内の他スタッフからは何しているんだろう状態・・・
当時のアーキテクチャ
社内システムに相乗りする形でスタート PHP、内製の独自フルスタックFW 社内システム部分はレンタルサーバー、チャットワークの部分はAWSで構築
ビジネスとしての転機
社内ツールとしてそれなりに稼働してきたこと・・・ 自社のUstreamチャンネルで社長がチラ見せしたとこと大反響
でしょ!
事態は急展開
四人プロジェクトに昇格 正式なプロダクトとしてローンチ
おかげ様でサービスは急成長
- サービスリリース初月で1万ユーザー達成
- Lineリリースもあり、チャットブームの波にのって口コミで大きく広がっていく。
- KDDI社と業務提携。エンタープライズのお客様への多数導入。
- 社名をChatWork株式会社へ変更、社運を賭ける覚悟を決める。
しかし、、、
積み重なっていた技術的負債
- 後ろを振り返らない開発の日々
- とにかく忘れ去られる前に走らないと死ぬ!(前失敗したトラウマ)
- 増え続ける人員、暗黙知
- 社内システムベースのアーキテクチャでは扱い切れない負荷、データ量に
技術的負債の状況
神クラスの誕生
ChatUtil.php 1クラス、1万行、メソッド数200弱
その他技術的負債
- 低いテストカバレッジ
- 一貫しない命名規則
- スケールを考慮されていないロジック
- オールドスタイルな開発フロー
- 本番環境と一致しない開発環境
技術的負債を貯め続けると最後はどうなるか?
- 遅れる 見積が大きく外れるようになる
- 落ちる 加速度的に増える負荷問題
何とかしなきゃ
ビジネスインパクトが無視できないものに
新規開発を一旦止め、技術的負債の解決へリソースを集中!
行ったこと
- CIの導入(Jenkins、TravisCI、Coveralls)
- 開発環境の整備(Vagrant、Ansible)
- PRベースの開発フロー(Github)
- 重い処理を疎結合にして非同期化(SQS)
- スケールアウトできるDBを採用(DynamoDB、CloudSearch)
- Scrumの導入(JIRA、Confluence)
- サーバー監視ツールの導入(NewRelic)
対策前のアーキテクチャ
対策後のアーキテクチャ
サービスの大幅安定化に成功
- Auto Scalingの導入によりダウンタイムが大幅に短縮化
- 負荷特性に応じてスケールアウト型のAWSのマネージメントサービスをフル活用。パフォーマンスが大きく上がった。
しかし、根本的な解決はできていない
- 対処療法的にある程度は改善できた
- しかし、根本の内製フレームワークの仕様、データ設計、API設計などの根本の問題は影響範囲が大きすぎてこれ以上の改善が困難
- 将来のグローバル展開を考えると、全然耐え切れるイメージがない・・・
これ以上の拡張はもう限界。。。
再実装しよう!
一番のハードルは、社内の理解
- 非エンジニアな役員陣にどう納得してもらうか?
- 技術的負債を理解してもらうのは大変難しい。。。
案の定・・・
- なんでそんなことするの?
- 技術的負債って何?
- 改善で何とかならないの?
- はじめからそうできなかったの?
建物の例をつかって説明しました
これで何とか納得してもらいました。
Martin Fowlerの犠牲的アーキテクチャ
長いスパンでのプロトタイピングのように、数年後に破棄することを前提にコードを書くという考え方。 失敗したのではなく、検証できたとみなす。
コードベースを破棄することで得られるメリット
- すでに確定した仕様でコードを再設計できる
- 最新の技術を制約なく利用可能
- 再実装時に仕様の再精査が可能
- 新メンバーがレガシーな仕様をキャッチアップしなくて良い
技術の選定
昨年のChatWorkブログで経緯を公開しました。 チャットワークの新しい開発言語とフレームワークを決める開発合宿を開催!その全貌を丸公開します。
アーキテクチャ選定合宿を開催
- 各エンジニアが、いまのチャットワークを再実装するならどの技術を選ぶかを選択
- 言語、フレームワーク、一切自由
- 合宿で仮実装して、選定する
選定合宿の結果
- Python / Flask
- Scala / Play framework
- PHP / Laravel
Scalaに決定!
Scalaを選んだ理由
- 静的言語としての保守性とパフォーマンスの高さ
- 動的言語からスイッチして成功した事例があること
- AWSはJava SDKが最も充実している
- チャットのリアルタイム処理と相性がいい
- PHPエンジニアでも短時間(開発合宿中)でそれなりに書けるようになった
大規模なシステムでは、静的言語の保守性が欲しくなる (他社の事例からも、第2言語には静的言語を選ぶ例が多い)
開発手法としてDDD(ドメイン駆動設計)を採用
- 大規模システムで評価が高く、Scalaとの相性もいいDDDを全面的に採用
- 非エンジニアもエンジニアもデザイナも、共通の言語「ユビキタス言語」を使って齟齬を防ぐ
- 仕様変更に強いアーキテクチャにできる
DDD勉強会を毎週開催
- チャットワークのドメインモデルをみんなで考える会
- ドメインモデルが実装ではクラス設計などに落ちてくる
- 軽食食べながら&飲みながらワイワイと
システム移行戦略
システム移行戦略のポイント
- 現行システムと新システムを平行して稼働させる
- 腐敗防止層を置いて、現行システムの設計に新システムを依存させない
- 新システムのDBは当初キャッシュだが、将来的にマスタDBとなる
新システム移行戦略のねらい
- ビッグバンリリースを避ける。デバイスごと、エンドポイントごとに少しづつ新システムへ移行可能(最初はiOSの予定)
- 新システム側に不具合があっても、マスタDBは現行システムが持つため安全
新ScalaシステムではAPIも刷新
クライアント側に大きく影響してしまうため、各デバイスでも合わせてシステム刷新することに
モバイル
- JavaScriptでコードを共有化するためにTitaniumを利用
- しかし、コードの共有は幻想だった・・・
- メモリリーク、クラッシュ多数。 ブラックボックスな不具合。
- OSアップデートについていけずノーガード状態
- ネイティブ化を決断。新APIに対応させる。
Web
- JavaScriptのコードも大規模化し、刷新を計画していた
- 大規模に向いているAltJSとしてScala.jsを採用予定
- サーバーサイドのScalaエンジニアでもフロントエンドが書けるように
Scala.js?
- CoffeeScriptやTypeScriptなどのような、JavaScriptを別の言語でかけるトランスパイラ
- 2013年のリリース当初は「Hello, world」で16MBのJavaScriptが生成され、ネタ扱い
- あれから大幅に改善され、 ついに Production Ready へ
- Play frameworkにも標準同梱
二槽式フロントエンド
- フロントエンドを、frontend-frontendとfrontend-backendに分ける
- frontend-frontendはUIをJavaScriptでカジュアルに。frontend-backendはScala.jsでドメインモデルを記述。
- frontend-backendはworkerにしてpostMessageでやりとり
※チャットワークのエンジニアが考えられたアーキテクチャだそうです
まとめ
- 社内システムから急成長したチャットワークのシステムが限界に
- サーバーサイドはScala、WebフロントエンドはScala.js、モバイルは各ネイティブ言語で書きなおすことに
- 巨大システムなので、順次移行できるような移行方法をとっています
さいごに
弊社でも利用しているChatWorkの裏側と今後の展望を伺えて、とてもおもしろかったです。Scala実装の新バージョンが待ちどうしいです。 また腐敗防止層などのDDDの考え方が興味深かったので、DDDを少し勉強してみようを思います。
InfoTalkは毎月開催しているので、面白いテーマがあれば参加してみると良いと思います。